<!DOCTYPE html>
<!-- saved from url=(0098)https://www.codeproject.com/Articles/620045/Custom-Controls-in-Win-API-Visual-Styles?display=Print -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>Custom Controls in Win32 API: Visual Styles - CodeProject</title> 
	<link type="text/css" rel="stylesheet" href="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/Main.min.css">

	
<meta http-equiv="content-language" content="en-US">

<meta name="Description" content="Paint your control consistently with standard/common controls, using the visual styles API.; Author: Martin Mitáš; Updated: 17 Mar 2014; Section: Windows API; Chapter: Platforms, Frameworks &amp; Libraries; Updated: 17 Mar 2014">
<meta name="Keywords" content="C, Windows, Win32, Win64, Visual-Studio, VS2010, custom-controls,Windows API,Platforms, Frameworks &amp; Libraries,Free source code, tutorials">
<meta name="Author" content="Martin Mitáš">
<meta name="Rating" content="General">
<meta name="Revisit-After" content="1 days">
<meta name="application-name" content="CodeProject">
<meta name="google-translate-customization" content="d908bb7ce7aff658-4c2f3a504525c916-g629383f736781a8a-13">

<link rel="dns-prefetch" href="https://ajax.googleapis.com/"> 
<link rel="canonical" href="https://www.codeproject.com/Articles/620045/%2fArticles%2f620045%2fCustom-Controls-in-Win-API-Visual-Styles">
<link rel="alternate" type="application/rss+xml" title="CodeProject Latest articles - All Topics" href="https://www.codeproject.com/WebServices/ArticleRSS.aspx?cat=1">
<link rel="alternate" type="application/rss+xml" title="CodeProject Latest articles - Artificial Intelligence" href="https://www.codeproject.com/WebServices/ArticleRSS.aspx?cat=31">
<link rel="alternate" type="application/rss+xml" title="CodeProject Lounge Postings" href="https://www.codeproject.com/webservices/LoungeRSS.aspx">
<meta name="robots" content="index, follow">
<link rel="search" type="application/opensearchdescription+xml" title="CodeProject" href="https://www.codeproject.com/info/OpenSearch.xml">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<link rel="apple-touch-icon" sizes="144x144" href="https://www.codeproject.com/favicon/apple-touch-icon.png"> 
<link rel="icon" type="image/png" sizes="32x32" href="https://www.codeproject.com/favicon/favicon-32x32.png"> 
<link rel="icon" type="image/png" sizes="16x16" href="https://www.codeproject.com/favicon/favicon-16x16.png"> 
<link rel="manifest" href="https://www.codeproject.com/favicon/manifest.json"> 
<link rel="mask-icon" href="https://www.codeproject.com/favicon/safari-pinned-tab.svg" color="#ff9900">
	
<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "TechArticle",
  "headline": "Custom Controls in Win32 API: Visual Styles",
  "url": "https://www.codeproject.com/Articles/620045/Custom-Controls-in-Win-API-Visual-Styles",
  "discussionUrl": "https://www.codeproject.com/Articles/620045/Custom-Controls-in-Win-API-Visual-Styles",
  "isFamilyFriendly": "true",
  "image": "https://www.codeproject.com/KB/vista/620045/Thumb-620045.png",
  "keywords": "C, Windows, Win32, Win64, Visual-Studio (VS2010), custom-controls",
  "commentCount": "12",
  "editor" : {
    "@type" : "Person",
    "name" : "Martin Mitáš",
    "url" : "https://www.codeproject.com/script/Membership/View.aspx?mid=5807385"
  },
  "license": "http://www.codeproject.com/info/cpol10.aspx",
  "publisher" : {
    "@type" : "Organization",
    "name" : "CodeProject"
  }
  "description": "Paint your control consistently with standard/common controls, using the visual styles API.",
  "upvoteCount": "54",
  "articleSection": "Windows API",
  "author" : [{
      "@type" : "Person",
      "name" : "Martin Mitáš",
      "url" : "https://www.codeproject.com/script/Membership/View.aspx?mid=5807385"
    }],
  "datePublished": "2013-07-21",
  "dateCreated": "2013-07-21",
  "dateModified": "2014-03-17",
  "aggregateRating" : {
    "@type" : "aggregateRating",
    "ratingValue" : 4.97,
    "ratingCount" : 54,
    "bestRating" : 5,
    "worstRating" : 1
  },
}
</script>
<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [{
    "@type": "ListItem",
    "position": 1,
    "item" : {
      "@id" : "/Chapters/8/Platforms-Frameworks-Libraries.aspx",
      "name" : "Platforms, Frameworks & Libraries"
    }
  },{
    "@type": "ListItem",
    "position": 2,
    "item" : {
      "@id" : "/KB/vista/",
      "name" : "Windows API"
    }
  }]
}
</script>
	<!--<base target="_top">--><base href="." target="_top">
	<script type="text/javascript" src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/jquery.2.2.4.min.js.下载"></script><script type="text/javascript">//<![CDATA[
if (typeof jQuery == 'undefined') {
    document.write(unescape("%3Cscript src='%2fscript%2fJS%2fjquery-2.2.4.min.js' type='text/javascript' %3E%3C/script%3E"));
}//]]></script><script src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/jquery-2.2.4.min.js.下载" type="text/javascript"></script>
<script type="text/javascript">//<![CDATA[
function defrm () { /* thanks twitter */ document.write = ''; window.top.location = window.self.location;  setTimeout(function() { document.body.innerHTML = ''; }, 0);  window.self.onload = function(evt) { document.body.innerHTML = ''; }; }if (window.top !== window.self) {  try {  if (window.top.location.host) { /* will throw */ } else { defrm(); /* chrome */ }  } catch (ex) { defrm(); /* everyone else */ } }if (typeof(DemoUrl)!='undefined')   document.write(unescape('%3Cme')+'ta http'+'-equiv="re'+'fresh"                  con'+'tent="1;url='+DemoUrl+unescape('"%3CE'));

//]]>
</script>

	




<script type="text/javascript">
	var _gaq = _gaq || [];
	_gaq.push(['_setAccount', 'UA-1735123-1']);
	_gaq.push(['_trackPageview']);
	_gaq.push(['_setDomainName', 'www.codeproject.com']);
	_gaq.push(['_setSessionTimeout', '1200']); 

	(function () {
		var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
		ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
		(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
	})(); 
</script><script type="text/javascript" async="" src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/ga.js.下载"></script>


</head>	

<body class="chrome chrome67 touch">

<a class="access-link" href="https://www.codeproject.com/Articles/620045/Custom-Controls-in-Win-API-Visual-Styles?display=Print#Main"><img alt="Click here to Skip to main content" src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/t.gif"></a>





<div class="page-background">

	
	

	

	
    <div id="ctl00_STM" class="site-top-menu fluid">
        <div class="main-content">
            
        </div>
    </div>

	
    <div id="ctl00_SH" class="site-header fluid">
        <div class="main-content">
            <div class="logo"><a href="https://www.codeproject.com/"><img id="ctl00_Logo" tabindex="1" title="CodeProject" src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/logo250x135.gif" alt="Home" style="height:135px;width:250px;border-width:0px;"></a></div>
            <div class="promo"></div>
        </div>
    </div>

	<a href="https://www.codeproject.com/Articles/620045/Custom-Controls-in-Win-API-Visual-Styles?display=Print#Main"><img alt="Click here to Skip to main content" class="access-link" src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/t.gif"></a>

	
			
	

	<div id="A" class="container-content-wrap fluid print"> 
	<div class="container-content">


		<div class="clearfix">
			<div class="container-breadcrumb float-left ">
				<div><a href="https://www.codeproject.com/script/Content/SiteMap.aspx">Articles</a> » <a href="https://www.codeproject.com/Chapters/8/Platforms-Frameworks-Libraries.aspx">Platforms, Frameworks &amp; Libraries</a> » <a href="https://www.codeproject.com/KB/vista/">Windows API</a> » <a href="https://www.codeproject.com/KB/vista/#General">General</a></div>
			</div>

            <div class="float-left">
				
			</div>

			<div class="edit-links float-right">
				
			</div>

			<div class="article-nav float-right">
                
				
			</div>
		</div>

		<table class="extended container-article-parts" cellpadding="0" cellspacing="0">
        <tbody><tr valign="top">
		<td width="117px" class="article-wing-left">

			

		</td>
		<td>
			
			<div id="AT" class="container-article  fluid tight"> 

				<div class="article">

					<form name="aspnetForm" method="post" action="https://www.codeproject.com/Articles/620045/Custom-Controls-in-Win-API-Visual-Styles?display=Print" id="aspnetForm" style="margin:0;padding:0">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="jzLsSimDggyHqU8hU6Ciaq4ZKjExJTJ2NHoMiLDAdljOuq4hf9FwqxBFjLi+Ak4LibwdSwiS19T92wyQMael9yFKrZmYQM3zoZeJSwKaU27IRT/VOjg6xPBSL6vllpvbTdhbFQG6/ubHTravQNQHDQ1chyLZ5vqKmQnolptgBNh1z2dTOKV3uKEfFFZlUQ1CVtzrN62+YOQeWGv1EXlYZz7qCXcq+i26dM2MzPA40v8Xn0tAwHiumW7O/d9cfGeOJr6NYLzF6GK77RixCUw/Etzfp1KflSLrX+WHy/zlEfSKteCIR6PD3Wq/NApclZL/b+OozOuCvz3s5RAyAy9HixI7hPmRezqpJbW/DY/HIdNPyjtHe2dzIMMpXz1TJwZYlzioubkxiFlX/eBh9v130Jt0aNnZwe/IOphUGFjwN5MS0gtxIhDw4VvVuGAOUqlvdXvHHufXp32iqV+bPfTVp7Epd318tDTXWvt2MkSAQxW7ggbc4Jn+zeLTMhYMrvuPcoGf7UARfFA71kPUHtDr2SXayPShA51jqtA2I3oLSvAPQg5QQuEV4uPfVd+mYxwo1bEs+KgJ5h5jvmhJHIW+WnkOgpRw4ky2VoUrQRmDLpWmyB2sivZ2fSJJVrBoqWZWIYWpSKO4xTAqhgBjQBIMy1MrULKqn+WkXAaYsw4fThxQ2YUIvibLS4e+RENU9k1C2tbSoW5VnEASAL1TpsBDXiu9U5oDMQKoPikhCJea+Tov2DmiLO6rS8FuOfywlSd0RG7TP6s8WgxCvveWN+0oTpNhOmmS2UL8nzRoqFFMEFvnDW461vrEFtAwvfWcrbD8fZJ5xBbqB0/zIaNV0PZm0340hom+mkeiu2rKNcU6j2BIiQ+tuU/L06+zwG7bOcKIZyPT1gDTSF3fG9As1IfoATPy+hntGCplzWEL0XmQSZtlhhAjencY14D3JqUAptMp+UzfYEeFsUseZnuLr+9F/Rde8ssHHP4OaML7dLAP+sCbxK48ASA4RxDBua8d+taddry3T5usdjHd0MRpaSDous9GUNQBI1Ssfv0zBaNAgqAztw36WXP+/fpNCYMkddWkMDe9fmZ9dNUt4AWmxpHEfB4ta7VD6OuXwwX1/hiyXbehWm/EPAwAeduKCNNYQ5x0deMon9nWRAX174qx5mlU1ICZ5f5u5ZTVHOtGcSbRqI+oh4MzVg7E4M0Ru6cqFOocZAdlqTR1L5LpCgkb6yuupcbthICD3fWt9XLCFWVuXpKIqS9BfHzXRDCphB4CgE9LijlRuJnsoxBdpWzvS3Kzzssdqu2DTTZy0F7rhQf6xqdJgykj+KOzs/6kVurTxn9htclZs4gw5USu2Fw+k8s1Xf1V2GuKDD71svj05r+pjdNtttr6VSpV8EX/3vnfVVOssQnagnDlv3QoiOlU1Nj6qgjLVjAMCHOpKi943Nm9/nOBwxEcLB+TO7dsO8KX5w8CMLQcRAV8g4/4GeebmXXQzg1g88fvJgN2lvGbi8eCp4bZXW/TjcAm+/uy42Z6Yl/R5Yi4jeIm21s0PMS6HRfgNvqc/wgOdMaZCYF46O3T46Bh/ZMjPlpu+A5uQi6VW3ZUqKSlKaqbL3dr+J0gAY3m/yqoObtAVT53iN4NitUgCA3IweUT0rZiGLYiCh55g55KYpzsqgdPCSMRwMSphjXnkMCq09TY73yo2nnoMNRfhH0SV+U9djeyr9VTTm3i4BKt5GZX5oRY548z0mpsLdVhdJaqIDYe9DvIwjVNVH8EosatQ9zUmjXHXo5nHFGfZGp0SWB2/YWXjS7hUFL4HwUjhVQaCM8W5m9NXfIIb7/WeFOlFaYlYN/MzYnzmDTZDDKQvcYBg55lRL/wy1qh/gcL4dLm4FwmAh17w8tFdOyvzj6otEeRveqHLfa5HZNPRcphJ9RbSj8m+Rs4L6uSbyxhkDWFt0VMyRqK/kltKnjcjJ1FfPzB3KyIdTG69X5l7mAGORHRZhnAJb/JELsWznzhajUbeAIigCLNobF10vCvKk8FOC5C5nUoXdpQA0d23JTR3b41GBGnizGC/UfpihbZP23MYgpsfgswWyNoJ5JfXyLn+xWcwjBB1XoUqFq2MpVdrKHweDCkM/VVSG529F1kiExxWUK5tYDMzfbKGkuQD7Isa3AyszMTwF66ttDE5VbdKTd75Jybz9P/lxlUwXAwgTEpvuWmaGRYhghVrrNzk7cjj9NicLy3sM+YQCLJzKXj7gKNparr7QwxzWoYfIfLlkIGkx85f5tPK0vdmLoOfYpeRHhrVxXzsXKHIbFeqDAS87J+Nb+7ndyPLc0UPznZDYzIkmbjdpSXEeT66ua7kbqO53rKVL7eag0BxOi5IhLAQNda5Tj4ZiA36mQ+MEWg4tUu+Qr4MRw4CfTxBZcAMt0dg5Vk">
</div>

<div>

	<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="10C1FD69">
</div>

					
					 
					<div class="header">
					    <a name="Main"></a>

					    
					    <a name="_articleTop" id="_articleTop"></a>
					    <div class="title">
					        <h1 id="ctl00_ArticleTitle">Custom Controls in Win32 API: Visual Styles</h1>
					    </div>

                        <div style="height:34px">
					        
					        <div class="entry float-left">

                                <img src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/58de2d085c17e28b8951315245dd408c.jpeg" id="ctl00_avatar" class="float-left avatar">

                                <div class="float-left">
                                    <div>
						                <span class="author"><a href="https://www.codeproject.com/script/Membership/View.aspx?mid=5807385" rel="author">Martin Mitáš</a></span>, 
						                <span class="date" title="Date last updated">
							            18 Mar 2014</span>
			                        </div>

                                    
						            
    						        	

                                </div>

    	                        	
                                <div class="float-left" style="margin: 25px 0 0 10px;">
	                                
	                            </div>
                         	    	
    
					        </div>

                            

						    <div id="ctl00_AdManagerWrap" class="float-right align-center">
                                
						    </div>

                        </div>

                        <div id="ctl00_description" class="summary">Paint your control consistently with standard/common controls, using the visual styles API.</div><span id="ctl00_thumbnailUrl" class="date" content="https://www.codeproject.com/KB/vista/620045/Thumb-620045.png"></span>			

                    </div>
                    
					
					

					

					
					
					

						
					

					

						
						<div id="contentdiv" class="text">
						



<ul class="download">
	<li><a href="https://www.codeproject.com/KB/vista/620045/vstyles.zip">Download visual styles example - 74.7 KB</a></li></ul>

<h2>Articles in this Series</h2>

<ul>
	<li><a href="http://www.codeproject.com/Articles/559385/Custom-Controls-in-Win32-API-The-Basics">Custom Controls in Win32 API: The Basics</a></li>	<li><a href="http://www.codeproject.com/Articles/617212/Custom-Controls-in-Win32-API-The-Painting">Custom Controls in Win32 API: The Painting</a></li>	<li>Custom Controls in Win32 API: Visual Styles</li>	<li><a href="http://www.codeproject.com/Articles/624495/Custom-Controls-in-Win32-API-Standard-Messages">Custom Controls in Win32 API: Standard Messages</a></li>	<li><a href="http://www.codeproject.com/Articles/646482/Custom-Controls-in-Win-API-Control-Customization">Custom Controls in Win32 API: Control Customization</a></li>	<li><a href="http://www.codeproject.com/Articles/744603/Custom-Controls-in-Win-API-Encapsulation-of-Cust">Custom Controls in Win32 API: Encapsulation of Customized Controls</a></li>	<li><a href="http://www.codeproject.com/Articles/1042516/Custom-Controls-in-Win-API-Scrolling">Custom Controls in Win32 API: Scrolling</a></li></ul>

<h2>Introduction</h2>

<p>The <a href="http://www.codeproject.com/Articles/617212/Custom-Controls-in-Win32-API-The-Painting">last time</a> we discussed the basics of custom controls' painting. Today, we will continue in the same direction and we will explore <em>visual styles</em> (a.k.a. <em>XP theming</em>).</p>

<p>For creation of high quality custom controls, using this API properly is essential, yet a quite complex task, so this article is longer than its predecessors and I kindly ask my readers for some patience when reading it. It will take some time before we really start using the API because first of all, we must take a look at Windows theming from a somewhat broader perspective.</p>

<h2>UXTHEME.DLL and COMCTL32.DLL</h2>

<p>The theming API is provided by the library <em>UXTHEME.DLL</em> which appeared in Windows XP. The two following screenshots demonstrate the difference between unthemed and themed user experience:</p>

<p align="center"><img alt="An unthemed dialog (Windows 2000)" height="500" src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/win2000.png" width="700"></p>

<div align="center" class="Caption">An unthemed dialog (Windows 2000)</div>

<p align="center"><img alt="A themed dialog (Windows 7, the default theme)" height="500" src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/win7.png" width="700"></p>

<div align="center" class="Caption">A themed dialog (Windows 7, the default theme Aero)</div>

<p>The introduction of this theming library also affected the common controls library, <em>COMCTL32.DLL</em>. For compatibility reasons, Windows XP (and all newer Windows versions) are equipped with two different versions of <em>COMCTL32.DLL</em>.</p>

<p>At the standard path <em>C:\Windows\System32\</em>, the old <em>COMCTL32.DLL</em> version 5 can be found. This library version contains the implementation of standard controls like list view, combo-box, etc., which are unaware of <em>UXTHEME.DLL</em> existence, hence applications linked with this library generally are not themed.</p>

<p>The newer version 6 of <em>COMCTL32.DLL</em> resides under <em>C:\Windows\WinSxS\</em>, available as a <em>side-by-side assembly</em>. Only applications explicitly manifesting their compatibility with the library version 6 use it. The other applications simply continue to use the version 5.</p>

<p>Also note, that historically some controls used to be implemented in <em>USER32.DLL</em> (window classes like, for example, <code>BUTTON</code> or <code>EDIT</code>), while others (known as common controls) resided in <em>COMCTL32.DLL</em>. This has changed with the introduction of <em>COMCTL32.DLL</em> version 6, and now all theming-aware controls live there.</p>

<p><strong>Gotcha:</strong> The old (unthemed) implementation of standard controls is still available in <em>USER32.DLL</em>. If you instruct the linker to link your application with <em>COMCTL32.DLL</em>, it may silently omit it if the application never calls any function from it. Hence I recommend you to call <code>InitCommonControls()</code> when initializing the application. Otherwise, the app may be just unthemed instead of not working, using the old controls, masking perfectly the root cause of the problem.</p>

<h2>Application Manifest</h2>

<p>The most usual and natural way of how the application can tell the system its desire to use version 6 of the library <em>COMCTL32.DLL</em>, is to specify it in its <em>manifest</em>. The manifest can be a separate file, but the preferred way is to embed it in the application binary as a resource.</p>

<p>As a separate file, it has to have exactly the same name as the application, with the suffix ".manifest" added (e.g., <em>example.exe.manifest</em> for application <em>example.exe</em>) and it must be located in the same directory.</p>

<p>When embedded as a resource, it has to have a resource ID 1 and type <code>RT_MANIFEST</code>, so typically the following line is present in the application's resource script (<em>.RC</em> file):</p>

<pre lang="text">1 RT_MANIFEST path/to/manifest.xml</pre>

<p>Either way, the manifest is an XML document and it should look like this:</p>

<pre lang="xml" data-lang-guess="XML"><span class="code-summarycomment">&lt;?</span><span class="code-summarycomment">xml</span><span class="code-summarycomment"> </span><span class="code-summarycomment">version</span><span class="code-keyword">="</span><span class="code-keyword">1.0"</span><span class="code-summarycomment"> </span><span class="code-summarycomment">encoding</span><span class="code-keyword">="</span><span class="code-keyword">UTF-8"</span><span class="code-summarycomment"> </span><span class="code-summarycomment">standalone</span><span class="code-keyword">="</span><span class="code-keyword">yes"</span><span class="code-summarycomment">?</span><span class="code-summarycomment">&gt;</span>
<span class="code-keyword">&lt;</span><span class="code-leadattribute">assembly</span><span class="code-attribute"> </span><span class="code-attribute">xmlns</span><span class="code-keyword">="</span><span class="code-keyword">urn:schemas-microsoft-com:asm.v1"</span><span class="code-attribute"> </span><span class="code-attribute">manifestVersion</span><span class="code-keyword">="</span><span class="code-keyword">1.0"</span><span class="code-keyword">&gt;</span>
    <span class="code-keyword">&lt;</span><span class="code-leadattribute">assemblyIdentity</span><span class="code-attribute"> </span><span class="code-attribute">version</span><span class="code-keyword">="</span><span class="code-keyword">1.0.0.0"</span><span class="code-attribute"> </span><span class="code-attribute">processorArchitecture</span><span class="code-keyword">="</span><span class="code-keyword">*"</span><span class="code-attribute"> </span><span class="code-attribute">name</span><span class="code-keyword">="</span><span class="code-keyword">app name"</span><span class="code-attribute"> </span><span class="code-attribute">type</span><span class="code-keyword">="</span><span class="code-keyword">win32"</span><span class="code-keyword">/</span><span class="code-keyword">&gt;</span>
    <span class="code-keyword">&lt;</span><span class="code-leadattribute">description</span><span class="code-keyword">&gt;</span>app description<span class="code-keyword">&lt;</span><span class="code-leadattribute">/description</span><span class="code-keyword">&gt;</span>
    <span class="code-keyword">&lt;</span><span class="code-leadattribute">dependency</span><span class="code-keyword">&gt;</span>
        <span class="code-keyword">&lt;</span><span class="code-leadattribute">dependentAssembly</span><span class="code-keyword">&gt;</span>
            <span class="code-keyword">&lt;</span><span class="code-leadattribute">assemblyIdentity</span><span class="code-attribute"> </span><span class="code-attribute">type</span><span class="code-keyword">="</span><span class="code-keyword">win32"</span><span class="code-attribute"> </span><span class="code-attribute">name</span><span class="code-keyword">="</span><span class="code-keyword">Microsoft.Windows.Common-Controls"</span><span class="code-attribute"> </span><span class="code-attribute">
</span><span class="code-attribute">
</span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute">version</span><span class="code-keyword">="</span><span class="code-keyword">6.0.0.0"</span><span class="code-attribute"> </span><span class="code-attribute">processorArchitecture</span><span class="code-keyword">="</span><span class="code-keyword">*"</span><span class="code-attribute"> </span><span class="code-attribute">
</span><span class="code-attribute">
</span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute"> </span><span class="code-attribute">publicKeyToken</span><span class="code-keyword">="</span><span class="code-keyword">6595b64144ccf1df"</span><span class="code-attribute"> </span><span class="code-attribute">language</span><span class="code-keyword">="</span><span class="code-keyword">*"</span><span class="code-keyword">/</span><span class="code-keyword">&gt;</span>
        <span class="code-keyword">&lt;</span><span class="code-leadattribute">/dependentAssembly</span><span class="code-keyword">&gt;</span>
    <span class="code-keyword">&lt;</span><span class="code-leadattribute">/dependency</span><span class="code-keyword">&gt;</span>
    <span class="code-keyword">&lt;</span><span class="code-leadattribute">ms_asmv2:trustInfo</span><span class="code-attribute"> </span><span class="code-attribute">xmlns</span><span class="code-keyword">="</span><span class="code-keyword">urn:schemas-microsoft-com:asm.v2"</span><span class="code-keyword">&gt;</span>
        <span class="code-keyword">&lt;</span><span class="code-leadattribute">ms_asmv2:security</span><span class="code-keyword">&gt;</span>
            <span class="code-keyword">&lt;</span><span class="code-leadattribute">ms_asmv2:requestedPrivileges</span><span class="code-keyword">&gt;</span>
                <span class="code-keyword">&lt;</span><span class="code-leadattribute">ms_asmv2:requestedExecutionLevel</span><span class="code-attribute"> </span><span class="code-attribute">level</span><span class="code-keyword">="</span><span class="code-keyword">asInvoker"</span><span class="code-attribute"> </span><span class="code-attribute">uiAccess</span><span class="code-keyword">="</span><span class="code-keyword">false"</span><span class="code-keyword">/</span><span class="code-keyword">&gt;</span>
            <span class="code-keyword">&lt;</span><span class="code-leadattribute">/ms_asmv2:requestedPrivileges</span><span class="code-keyword">&gt;</span>
        <span class="code-keyword">&lt;</span><span class="code-leadattribute">/ms_asmv2:security</span><span class="code-keyword">&gt;</span>
    <span class="code-keyword">&lt;</span><span class="code-leadattribute">/ms_asmv2:trustInfo</span><span class="code-keyword">&gt;</span>
<span class="code-keyword">&lt;</span><span class="code-leadattribute">/assembly</span><span class="code-keyword">&gt;</span></pre>

<p>Of course for your application the manifest should be adapted to use its name, description, version, and also the processor it is supposed to run on (<em>"X86"</em>, <em>"amd64"</em>, or <em>"*"</em> meaning any CPU type) in the first <code>&lt;assemblyIdentity&gt;</code> tag.</p>

<p>When an application is being launched on Windows XP or newer, the system (in particular, the application loader) examines the binary and looks whether it can find the manifest. If yes, then the application loader loads DLLs in the versions to satisfy the requirements in the manifest. (Strictly speaking this works only for DLLs available as side-by-side assemblies, not for every DLL. But <em>COMCTL32.DLL</em> fulfills this requirement.)</p>

<p>In our context, the most interesting part of the manifest is the specification of the dependent assembly, identified as <code>Microsoft.Windows.Common-Controls</code>, where we explicitly ask the system for version 6 of <em>COMCTL32.DLL</em>.</p>

<p>Hence, when implementing a reusable control, we should naturally follow and respect the application's manifest too. If the app proclaims it supports <em>COMCTL32.DLL</em> version 6, the custom control should follow it and use the theming API as <em>COMCTL32.DLL</em> does. When the app is not themed, the custom control should respect it and its look should be consistent with it.</p>

<p>Even if the control is implemented in a separate DLL and it has no control over in what application its code is executed in, we can use the version of <em>COMCTL32.DLL</em> as an indicator for the decision making at run time:</p>

<pre lang="C++"><span class="code-keyword">#include</span><span class="code-preprocessor"> <span class="code-keyword">&lt;</span><span class="code-leadattribute">windows.h</span><span class="code-keyword">&gt;</span>
</span><span class="code-keyword">#include</span><span class="code-preprocessor"> <span class="code-keyword">&lt;</span><span class="code-leadattribute">shlwapi.h</span><span class="code-keyword">&gt;</span>
</span>
BOOL ShouldUseUxThemeDll(<span class="code-keyword">void</span>) 
{
    HMODULE hDll;
    DWORD dwMajorVersion = <span class="code-digit">0</span>;

    hDll = LoadLibrary(_T(<span class="code-string">"</span><span class="code-string">COMCTL32.DLL"</span>));
    <span class="code-keyword">if</span>(hDll != NULL) {
        DLLGETVERSIONPROC fn_DllGetVersion;
        DLLVERSIONINFO vi;

        fn_DllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hDll, <span class="code-string">"</span><span class="code-string">DllGetVersion"</span>);
        <span class="code-keyword">if</span>(fn_DllGetVersion != NULL) {
            vi.cbSize = <span class="code-keyword">sizeof</span>(DLLVERSIONINFO);
            fn_DllGetVersion(&amp;vi);
            dwMajorVersion = vi.dwMajorVersion;
        }
        FreeLibrary(hDll);
    }

    <span class="code-keyword">return</span> (dwMajorVersion &gt;= <span class="code-digit">6</span>);
}</pre>

<p>Note that the return value of this function does not change for the life time of the application. (That is, unless the application does something nasty with <code>FreeLibrary()</code> and <code>LoadLibrary()</code>, changing the version of <em>COMCTL32.DLL</em> in process run time. That is such an obscure case, that, in my opinion, we can solve this issue by ignoring it...).</p>

<h2>Disabling Visual Styles</h2>

<p>Even if an application asks for <em>COMCTL32.DLL</em> version 6 using the manifest, the standard controls may still be painted unthemed, as (in some Windows versions) the user can disable the theming in the whole user session (in Control Panels), or for the particular application (the Properties of the particular <em>.exe</em> file, Compatibility tab).</p>

<p><strong>Note</strong>: The setting in Control Panel applies immediately to all (theme-aware) applications, even for those already running. Disabling visual styles on the Compatibility tab of the application's Properties does not affect already running processes. It only applies for any .EXE started after the change.</p>

<p><strong>Gotcha</strong>: At least on 64-bit Windows 7, disabling visual themes for a 64-bit application in the Compatibility tab is silently ignored by the system. I guess Microsoft felt no need to provide that compatibility option for 64-bit applications: Prior to Windows XP, there were no 64-bit programs in the first place. So, likely, they just forgot to hide or disable the check-box for 64-bit apps on that dialog.</p>

<p>On Windows 8, the option to disable themes for an application has disappeared altogether.</p>

<h2>Compatibility and Testing</h2>

<p>Windows 2000 (and older) do not support themes at all and the library <em>UXTHEME.DLL</em> does not exist there. If you aspire to support Windows 2000, then you should load <em>UXTHEME.DLL</em> in run time with <code>LoadLibrary()</code> and <code>GetProcAddress()</code>. If that fails, fall back in your control implementation to the non-themed GDI code paths.</p>

<p>Even when <em>UXTHEME.DLL</em> is present, different Windows versions come with quite different default themes and a small set of alternative themes (usually only color variations of the default one). (Only Windows Vista and 7 share the same themes.)</p>

<p>Of course all of that increases the amount of circumstances under which the control should be tested. As a bare minimum, you should test your control on Windows XP, Windows 7 (or Vista), and on Windows 10 (or 8), and also while the themes are disabled.</p>

<h2>Using UXTHEME.DLL</h2>

<p>To use the theming API, you need to link (or load in run time) <em>UXTHEME.DLL</em>, and include its header <em>uxtheme.h</em>. There are also accompanying headers <em>vsstyle.h</em> and <em>vssym32.h</em> we will mention later.</p>

<p><strong>Note</strong>: <em>UXTHEME.DLL</em> does not follow the historic Win32 API string duality. Whenever dealing with strings, Win32 API usually provides two functions for the same thing, one for Unicode (functions ending with the suffix "-W') and the other one for ANSI strings (suffix "-A"), and a macro (without a suffix) which resolves to one of those depending on whether macro <code>UNICODE</code> is defined.</p>

<p>On the other hand <em>UXTHEME.DLL</em> uses strictly Unicode. It includes functions for painting text as well as various string identifiers (i.e., theme class and subclass names and values of string properties; these terms shall be explained further in the article).</p>

<h2>Theme Definition</h2>

<p><em>UXTHEME.DLL</em> itself is a relatively simple DLL. It actually does not know anything about how to paint a particular control or its part. Instead, most of its functions just know how to access the currently active theme data, which I call <em>theme definition</em> for the purposes of this article. It is the theme definition as provided on Windows (and the lack of its documentation) which causes more difficulties for the implementation of custom controls rather than <em>UXTHEME.DLL</em> itself.</p>

<p>The theme definition, in general, is a structured storage which defines a hierarchy of some objects (classes, subclasses, parts, states; we will discuss them below) and associates them with various resources (mainly images) and properties describing many aspects of them.</p>

<p>The core of the storage is a resource-only DLL (albeit with a different file extension). For example on Windows 7, the DLL is usually on the path <em>C:\Windows\Resources\Themes\Aero\aero.msstyles</em>. However your application should not rely on such an implementation detail at all.</p>

<p>On Windows XP the default them definition is called Luna. On Vista and 7 it is Aero. You may already know these names as they were appearing even in Microsoft marketing materials.</p>

<p>The top-level category in the hierarchy of objects defined by the theme definition is <em>class</em>. Please do not confuse the theme class with the term from object-oriented programming. The class is identified with its string name (the second parameter of <code>OpenThemeData()</code>) and in most (but not all) cases it provides data for a particular standard control, or other aspects of the user interface (e.g., the Start menu, Control Panels, etc.).</p>

<p>Some theme classes actually have the same name as some of the window class names of standard controls (e.g., <code>BUTTON</code>, <code>EDIT</code>, <code>TREEVIEW</code>) but in general, the namespace of both are different and there are many standard window classes which do not have their own dedicated counterpart in the Windows theme definitions, and vice versa. A prominent example of such a theme class can be <code>TEXTSTYLE</code> which defines mainly font attributes for various text labels, for general use by applications. (Note though this theme class was added in Aero. Luna on Windows XP does not have it.)</p>

<p>There are also subclasses which may provide different, alternative, data for the same kind of control or other elements of the Windows user interface, but we will cover them a bit later, to make the main principles easier to understand.</p>

<p>In the second level, below the class in the hierarchy, there are <em>parts</em>. A part is identified by an integer and it describes some partial aspect of the theme class which can be painted independently on the other parts of the same theme class, e.g. a border frame, a background, a glyph, a button for the scrollbar or a combo box.</p>

<p>In the third level of the hierarchy, there is a <em>state</em>. Like part, it is also identified by an integer. Different states of a single part are used to reflect various states of the control, e.g., when it is disabled, when it has focus, or when it is hot (i.e., under the mouse cursor). Parts which are not supposed to change their look according to the control's internal state often have only one state, usually identified by value 1. Other parts may have many states.</p>

<p>Many API functions working with themes take the part and state together with the theme handle as their input. In relatively rare cases when you need to refer to the part as a whole, you may use state=0 as the API guarantees no state has this identifier. The same stands for parts. Part 0 means the caller has no particular part in mind.</p>

<p>Furthermore, each object on each level of the hierarchy (including the theme definition as a whole) can have many properties associated with it. The properties vary a lot and can also have different types and they describe many attributes of the objects. Again, we will say a few words about them later.</p>

<p>Windows SDK provides headers <em>vssym32.h</em> and <em>vsstyle.h</em> which provide some symbolic identifiers to the parts and states (enumerations) and also for properties (defined as preprocessor macros). (Some older tutorials on the net may use <em>tmschema.h</em> instead. But Microsoft declared this header obsolete in more recent Windows SDKs. It is less complete and incompatible with the newer headers so avoid it in new code.)</p>

<p>For example, the standard window class <code>BUTTON</code> has a corresponding theme class <code>BUTTON</code>, and it consists of parts:</p>

<pre><span class="code-keyword">enum</span> BUTTONPARTS {
    BP_PUSHBUTTON = <span class="code-digit">1</span>,
    BP_RADIOBUTTON = <span class="code-digit">2</span>,
    BP_CHECKBOX = <span class="code-digit">3</span>,
    BP_GROUPBOX = <span class="code-digit">4</span>,
    BP_USERBUTTON = <span class="code-digit">5</span>,
    BP_COMMANDLINK = <span class="code-digit">6</span>,
    BP_COMMANDLINKGLYPH = <span class="code-digit">7</span>
};</pre>

<p>Then there are other enumerations which list styles for each button part, for example for <code>PB_PUSHBUTTON</code>:</p>

<pre><span class="code-keyword">enum</span> PUSHBUTTONSTATES {
    PBS_NORMAL = <span class="code-digit">1</span>,
    PBS_HOT = <span class="code-digit">2</span>,
    PBS_PRESSED = <span class="code-digit">3</span>,
    PBS_DISABLED = <span class="code-digit">4</span>,
    PBS_DEFAULTED = <span class="code-digit">5</span>,
    PBS_DEFAULTED_ANIMATING = <span class="code-digit">6</span>
};</pre>

<h2>Theme Handle Management</h2>

<p>Now, finally, we get to the point where we can start exploring the theming API itself.</p>

<p>Once the control decides it wants to use the visual styles, it needs a valid theme handle (<code>HTHEME</code>). The handle is an opaque type representing the given theme class (or subclass). This handle can be obtained with the function <code>OpenThemeData()</code> (second parameter of it is the class name), and released with <code>CloseThemeData()</code>. All functions for themed painting expect this handle as their first parameter.</p>

<p><strong>Note</strong>: The application must be also ready for the situation when the desired theme can not be opened and <code>OpenThemeData()</code> returns <code>NULL</code>. That can happen either because the currently selected theme does not know the desired theme class name, or because theming is disabled as discussed above. Typically, the control should then fall back to a code path, which paints the control without themes, in the plain old way to fit in the gray old unthemed dialog.</p>

<p>Furthermore, the control has to reopen the theme handle and repaint itself with it whenever it receives the message <code>WM_THEMECHANGED</code>, which is a notification that some relevant theme settings have changed (e.g., the user has selected a different theme in Control Panel).</p>

<p>So, in a typical control implementation, the relevant parts of the control implementation may look like this:</p>

<pre lang="C++"><span class="code-keyword">#include</span><span class="code-preprocessor"> <span class="code-keyword">&lt;</span><span class="code-leadattribute">uxtheme.h</span><span class="code-keyword">&gt;</span>
</span>
<span class="code-comment">//</span><span class="code-comment"> Class name for this control.</span>
<span class="code-keyword">static</span> <span class="code-keyword">const</span> WCHAR[] wszClass = L<span class="code-string">"</span><span class="code-string">BUTTON"</span>

<span class="code-keyword">typedef</span> <span class="code-keyword">struct</span> CustomData_tag CustomData;
<span class="code-keyword">struct</span> CustomData_tag {
    HWND hwnd;       <span class="code-comment">//</span><span class="code-comment"> handle of control window</span>
    HTHEME hTheme;   <span class="code-comment">//</span><span class="code-comment"> theme handle (NULL when not themed)</span>
    <span class="code-comment">//</span><span class="code-comment"> ...</span>
};

<span class="code-keyword">static</span> <span class="code-keyword">void</span>
CustomPaint(CustomData* pData, HDC hDC, RECT* rcDirty, BOOL bErase)
{
    <span class="code-keyword">if</span>(pData-&gt;hTheme != NULL) {
        <span class="code-comment">//</span><span class="code-comment"> Paint with themes.</span>
        <span class="code-comment">//</span><span class="code-comment"> ...</span>
    } <span class="code-keyword">else</span> {
        <span class="code-comment">//</span><span class="code-comment"> Fallback to old simple grayish look, painted with plain GDI.</span>
        <span class="code-comment">//</span><span class="code-comment"> ...</span>
    }
}

<span class="code-keyword">static</span> LRESULT CALLBACK
CustomProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    CustomData* pData = (CustomData*) GetWindowLongPtr(hwnd, <span class="code-digit">0</span>);

    <span class="code-keyword">switch</span>(uMsg) {
        <span class="code-keyword">case</span> WM_ERASEBKGND:
            <span class="code-keyword">return</span> FALSE;

        <span class="code-keyword">case</span> WM_PAINT:
        {
            PAINTSTRUCT ps;
            BeginPaint(hwnd, &amp;ps);
            CustomPaint(pCustom, ps.hdc, &amp;ps.rcPaint, ps.fErase);
            EndPaint(hwnd, &amp;ps);
            <span class="code-keyword">return</span> <span class="code-digit">0</span>;
        }
 
        <span class="code-keyword">case</span> WM_THEMECHANGED:
            <span class="code-keyword">if</span>(pData-&gt;hTheme)
                CloseThemeData(pData-&gt;hTheme);
            pData-&gt;hTheme = OpenThemeData(hwnd, wszClass);
            InvalidateRect(hwnd, NULL, TRUE);
            <span class="code-keyword">return</span> <span class="code-digit">0</span>;

        <span class="code-keyword">case</span> WM_CREATE:
            <span class="code-keyword">if</span>(!DefWindowProc(hwnd, uMsg, wParam, lParam))
                <span class="code-keyword">return</span> -<span class="code-digit">1</span>;
            pData-&gt;hTheme = OpenThemeData(hwnd, wszClass);
            <span class="code-keyword">return</span> <span class="code-digit">0</span>;

        <span class="code-keyword">case</span> WM_DESTROY:
            <span class="code-keyword">if</span>(pData-&gt;hTheme)
                CloseThemeData(pData-&gt;hTheme);
            <span class="code-keyword">break</span>;

        <span class="code-keyword">case</span> WM_NCCREATE:
            <span class="code-keyword">if</span>(!DefWindowProc(hwnd, uMsg, wParam, lParam))
                <span class="code-keyword">return</span> FALSE;
            pData = malloc(<span class="code-keyword">sizeof</span>(CustomData));
            <span class="code-keyword">if</span>(pData == NULL)
                <span class="code-keyword">return</span> FALSE;
            ZeroMemory(pData, <span class="code-keyword">sizeof</span>(CustomData));
            pData-&gt;hwnd = hwnd;
            SetWindowLongPtr(hwnd, <span class="code-digit">0</span>, (LONG_PTR)pData);
            <span class="code-keyword">return</span> TRUE;

        <span class="code-keyword">case</span> WM_NCDESTROY:
            <span class="code-keyword">if</span>(pData != NULL)
                free(pData);
            <span class="code-keyword">break</span>;
    }

    <span class="code-keyword">return</span> DefWindowProc(hwnd, uMsg, wParam, lParam);
}</pre>

<p>Note that for the sake of readability, this example has skipped the checking of the old <em>COMCTL32.DLL</em> version with <code>ShouldUseUxThemeDll()</code> as recommended in the earlier section. The attached downloadable code (at the top of this article) is more complete in this regard.</p>

<p>Also note we will supplement the function <code>CustomPaint()</code> with some real painting code later in this article, after a short intermezzo.</p>

<h2>Useless IsThemeActive() and IsAppThemed()</h2>

<p>Equipped with the knowledge about theme handle management, let's return a bit back to the discussion about when we should paint with themes and when not to. When checking whether the application or control should be painted with themes, there are two <em>UXTHEME.DLL</em> functions, <code>IsThemeActive()</code> and <code>IsAppThemed()</code>, which developers often attempt to use for this purpose but which cause a lot of confusion. Therefore, let's explain them a bit more.</p>

<p><code>IsThemeActive()</code> only asks whether the user has enabled themes in his session. It usually returns <code>TRUE</code>, unless the user selected the classical look and feel in Control Panel (so, on Windows 8, it always returns <code>TRUE</code>). In particular, remember it can return <code>TRUE</code> even, when the theming is disabled for the particular application in its Properties, or when the application otherwise is unaware of themes and uses <em>COMCTL32.DLL</em> version 5. All that matters is the global setting in the Control Panel.</p>

<p>When the setting has changed, all the application's top-level windows receive <code>WM_THEMECHANGED</code> and they (unless the top-level windows suppress it) forward the message to all controls (<code>DefWindowProc()</code> does that). As explained earlier, the controls then (re)open their theme handle(s) and, when the theming is disabled in that particular time, they get <code>NULL</code> handles.</p>

<p>The other function, <code>IsAppThemed()</code>, does much more. Actually too much, in my opinion. It checks that themes are allowed globally (the same as <code>IsThemeActive()</code>) and that the application wants to be themed (manifest) and that themes are not disabled (Compatibility tab of its Properties). It returns <code>TRUE</code> only when all the three conditions are true. In other words, it asks whether <code>OpenThemeData()</code> would, for reasonable valid input parameters, return a valid non-<code>NULL</code> theme handle at the moment. If it returns <code>FALSE</code>, any call to <code>OpenThemeData()</code> is guaranteed to return <code>NULL</code>.</p>

<p>As both functions depend on the user settings, the return value of both functions can vary during the application's run time. Due to this property of the functions, the application or control would have to call them again always when it gets <code>WM_THEMECHANGED</code>, but then the work can be fully handled by <code>OpenThemeData()</code>. Because of that, I consider both of these functions mostly useless.</p>

<p>Instead of them, I recommend to use my function <code>ShouldUseUxThemeDll()</code>. Actually the function <code>ShouldUseUxThemeDll()</code> is similar to <code>IsAppThemed()</code> but it ignores the user settings. Hence, its return value is the same during the app's life time. So it may be called just once during application or DLL initialization (though not in the context of <code>DllMain()</code>). When this function returns <code>FALSE</code>, avoid using the theming API altogether for the whole life time of your application. When it returns <code>TRUE</code>, use the API and rely on <code>OpenThemeData()</code> and <code>WM_THEMECHANGED</code> to reflect the run-time settings.</p>

<p>An additional added value of <code>ShouldUseUxThemeDll()</code> is that it works also on older Windows versions, prior to Windows XP. If you want to be compatible with, for example, Windows 2000 and load <em>UXTHEME.DLL</em> in run time with <code>LoadLibrary()</code>, you simply need to load it only when the function <code>ShouldUseUxThemeDll()</code> returns <code>TRUE</code>.</p>

<h2>Themed Painting</h2>

<p>Alright, back to the themed painting.</p>

<p>Let's supplement code from the section about handle management to paint a button-like control, for example. Note the control is not interactive so we use a constant part and state. Real controls would remember and change the state of the control by monitoring various mouse and keyboard messages in a window procedure.</p>

<pre lang="C++"><span class="code-keyword">static</span> <span class="code-keyword">void</span> CustomPaint(CustomData* pData, HDC hDC, RECT* rcDirty, BOOL bErase)
{
    RECT rect;
    GetClientRect(pData-&gt;hwnd, &amp;rect);

    <span class="code-keyword">if</span>(pData-&gt;hTheme != NULL) {
        <span class="code-keyword">int</span> part;
        <span class="code-keyword">int</span> state;

        part = BP_BUTTON;
        state = PBS_NORMAL;
       
        <span class="code-keyword">if</span>(IsThemeBackgroundPartiallyTransparent(pData-&gt;hTheme, part, state))
            DrawThemeParentBackground(pData-&gt;hwnd, hDC, &amp;rect);
        DrawThemeBackground(pData-&gt;hTheme, hDC, part, state, &amp;rect, &amp;rect);
    } <span class="code-keyword">else</span> {
        <span class="code-comment">//</span><span class="code-comment"> Fallback to old simple grayish look, painted with plain GDI.</span>
        DrawFrameControl(hDC, &amp;rect, DFC_BUTTON, DFCS_BUTTONPUSH);
    }
}</pre>

<p>The code above is almost canonical. Every tutorial on the topic shows something like this snippet of code. The essential part of theming is its support for (partially) transparent controls so the painting code has to reflect this and (when needed) ask the parent window to paint to fill the transparent areas.</p>

<p>For example, a button in Windows theme definitions has rounded corners and this way, it is the parent's job to paint the few pixels exposed by them.</p>

<p>By the way, although I haven't verified this, I believe <code>IsThemeBackgroundPartiallyTransparent()</code> actually makes some magic based on sending the <code>WM_PRINTCLIENT</code> message to the parent. We already discussed this message in <a href="http://www.codeproject.com/Articles/617212/Custom-Controls-in-Win32-API-The-Painting">the previous article</a>.</p>

<p>Another useful function is <code>DrawThemeText()</code> (and also <code>DraweThemeTextEx()</code>, since Vista) which is intended for painting control labels. The function uses font and other text attributes as set by the theme definition. In practice however, both Luna and Aero, do not define any font or text properties for majority of classes/parts/states, which just leads the function to paint with <code>HFONT</code> currently selected into the used device context and only a few standard controls actually paint themselves with this function. Most of them stick with the old GDI <code>TextOut</code> or <code>DrawText()</code> to paint with a font determined by the latest <code>WM_SETFONT</code>, but that is another topic.</p>

<p><strong>Note</strong>: When the theme does not define any font properties for the class/part/state used, <code>DrawThemeText()</code> simply paints with the font currently selected in the device context.</p>

<p>The API provides a few more functions for painting with themes like <code>DrawThemeEdge()</code> or <code>DrawThemeIcon()</code>. AFAIK, they are rarely used and we will not pay any special attention to them here.</p>

<h2>Theme Subclasses</h2>

<p>Let's now talk a bit about the theme subclasses. First of all, note that the term has nothing common with the technique called <em>control subclassing</em>, which is used for augmenting an existing control by implanting another window procedure via <code>SetWindowLongPtr(hwnd, GWLP_WNDPROC, pfn_WinProc)</code>.</p>

<p>The <em>theme subclass</em> is indeed something different. It is an alternative set of properties and resources in the theme definition, associated with the class, and differentiated from the normal class (and from other subclasses of the same class) by some string identifier: the subclass name.</p>

<p>That allows applications to change the look of some control by enforcing some subclass name to it. Many programs which are integral parts of Windows (including <em>explorer.exe</em> which is responsible for managing the desktop and the open folder windows) take advantage of this feature. It is no accident that the Aero theme definition provides a subclass named <code>EXPLORER</code> for many standard controls.</p>

<p>The screenshot below demonstrates how the tree view control differs in Aero (Windows 7), depending on whether it uses the standard class <code>TREEVIEW</code>, or when it is told to use the <code>EXPLORER</code> subclass of it:</p>

<p align="center"><img height="300" src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/subclass.png" width="460"></p>

<p>It can be seen that the two tree views look a bit different and even have a bit different item dimensions. From a programmatic point of view, the difference is achieved with this single line of code which forces the right control to use the subclass:</p>

<pre lang="C++">SetWindowTheme(hwndTreeOnRight, L<span class="code-string">"</span><span class="code-string">EXPLORER"</span>, NULL);</pre>

<p>That one line has the following effect: Window manager remembers the subclass name in association with the control, until the window dies or the function is used once again to reset the subclass name. Whenever the control implementation calls <code>OpenThemeData()</code> (with its own window handle as the first parameter), <em>UXTHEME.DLL</em> returns a handle to the subclass data, not the parent class itself. Also the function <code>SetWindowTheme()</code> immediately sends <code>WM_THEMECHANGED</code> to the given control so in response, the control reopens the theme handle and repaints itself, applying the subclass instantly.</p>

<p>Right now, you will probably ask about the last parameter of <code>SetWindowTheme()</code>, especially if you have read the documentation of the function on MSDN, as the description there is very cryptic. To be honest, I am not too sure about it. I think (but never verified) that it allows to associate a class (not subclass) name with the control and hence to override the class name the control itself uses whenever it calls <code>OpenThemeData()</code>. (This speculation is based on an information that using <code>L" "</code> as the last parameter forces the particular window handle to paint itself without any theme. That, I guess, is caused by the fact that the theme definition does not know a class named with a space.)</p>

<h2>Theme Properties</h2>

<p>I already disclosed that properties are some data associated with classes, subclasses, parts, and states in the theme definition, or with the theme definition itself.</p>

<p>The API defines a huge number of properties, and usually each object in the theme definition defines just a small portion of them. Various properties are of different types and it is this variability of properties which reflects in the API itself: Majority of its functions are intended for retrieving values of the properties.</p>

<p>There are various enumeration properties (<code>GetThemeEnumValue()</code>), integer properties (<code>GetThemeIntValue()</code>), string properties (<code>GetThemeStringValue()</code>), boolean properties (<code>GetThemeBoolValue()</code>), color properties (<code>GetThemeColorValue</code>), and much more. It likely does not make any sense to list all their types here.</p>

<p>The good news, though, is that in most cases, the app or control does not need to retrieve them. Instead the painting functions of the theming API reflect them automatically. For example, the property <code>TMT_BGTYPE</code> specifies whether painting a background of a class/part/state it is associated to, should be painted as bliting an image, painting a frame, or if no background should be painted at all. Depending on that, other properties may specify what image or what color to use and how. The function <code>DrawThemeBackground()</code> retrieves the relevant properties and follows them.</p>

<p>This is why we won't talk much about properties: There are hundreds of them and I have ever used only a few of them. That said with one exception: There are some useful global properties, i.e. properties not related to any object in the theme definition, but with the theme definition itself. We will cover these in next section.</p>

<p>We may also touch a few other properties in future articles when we talk about some topic when using a specific property is needed.</p>

<h2>Useful Global Properties</h2>

<p>As mentioned above, there are also some global properties, meaning they apply to the whole system as long as the particular theme definition is in use. Actually many of these properties are a replacement of system parameters as retrieved with some old functions provided by <em>USER32.DLL</em>.</p>

<p>All of <em>UXTHEME.DLL</em> functions whose names begin with <code>GetThemeSys...()</code> are of this nature. One nice feature of this set of functions is the fact that when no theme definition applies (theme handle is <code>NULL</code>), the functions fall back to retrieve the right values with the corresponding <em>USER32.DLL</em> function for you.</p>

<p>So let's provide a small table of how these translate to each other:</p>


	<table align="center" class="ArticleTable"><thead>		<tr>			<th colspan="2"><em>UXTHEME.DLL</em></th>			<th colspan="2"><em>USER32.DLL</em></th>		</tr>		<tr>			<th>Function</th>			<th>Fundamental constant</th>			<th>Function</th>			<th>Fundamental constant</th>		</tr>	</thead>	<tbody>		<tr>			<td><code>GetThemeSysBool()</code></td>			<td><code>TMT_FLATMENUS</code></td>			<td><code>SystemParametersInfo()</code></td>			<td><code>SPI_GETFLATMENU</code></td>		</tr>		<tr>			<td><code>GetThemeSysColor()</code></td>			<td>&nbsp;</td>			<td><code>GetSysColor()</code></td>			<td>&nbsp;</td>		</tr>		<tr>			<td><code>GetThemeSysColorBrush()</code></td>			<td>&nbsp;</td>			<td><code>GetSysColorBrush()</code></td>			<td>&nbsp;</td>		</tr>		<tr>			<td rowspan="2"><code>GetThemeSysFont()</code></td>			<td><code>TMT_ICONTITLEFONT</code></td>			<td rowspan="2"><code>SystemParametersInfo()</code></td>			<td><code>SPI_GETICONTITLELOGFONT</code></td>		</tr>		<tr>			<td>the other ones</td>			<td><code>SPI_GETNONCLIENTMETRICS</code></td>		</tr>		<tr>			<td><code>GetThemeSysInt()</code></td>			<td>&nbsp;</td>			<td>no counterpart</td>			<td>&nbsp;</td>		</tr>		<tr>			<td><code>GetThemeSysSize()</code></td>			<td>&nbsp;</td>			<td><code>GetSystemMetrics()</code></td>			<td>&nbsp;</td>		</tr>		<tr>			<td><code>GetThemeSysString()</code></td>			<td>&nbsp;</td>			<td>no counterpart</td>			<td>&nbsp;</td>		</tr>	</tbody></table>

<p><strong>Note</strong>: Wherever the fundamental constant is not filled in the table, both functions share the set of allowed parameters (with the same meaning).</p>

<p>Only in case you want to also support Windows 2000 or older, and hence need to deal with the possibility of missing <em>UXTHEME.DLL</em>, you may need to implement the fallback manually.</p>

<h2>Troubleshooting</h2>

<p>So far, you could quite easily get an impression that once you solve the problem whether to use the theming API, the painting with the visual themes is then quite straightforward. But in controls of more complex nature, you can encounter many problems. Below I summarize the problems I have been facing when implementing my controls, especially controls in the <a href="http://mctrl.org/">mCtrl project</a>.</p>

<p>Unfortunately, for many of them, there is no simple solution (as far as I know). Still, I believe it is valuable to list the problems here. At least, you should be aware of a trap before you decide to step into it. It is simply a matter of fact that using this API requires often a trial-and-error approach to find a feasible way to implement your control.</p>

<h3>Gotcha: Heavily Under-Documented</h3>

<p>The biggest problem of the API is the lack of good documentation. MSDN documents fairly well all the functions and types of the API. But documentation of the theme definition objects, i.e., classes and subclasses, as well as their parts and states, consists mainly of pure listings of their identifiers.</p>

<p>There is no documentation of what each class, subclass, part, or state is meant for. Often it is quite obvious from the name of the class/sublclass or part/state identifier, but in many cases it is not.</p>

<p>Even when it is obvious, it is not documented which Windows introduced them, or under which circumstances they are usable. For example some parts are only used by a standard control when you switch it to a particular subclass. It is a case of the class <code>TREEVIEW</code> which defines (among others) the part <code>TVP_HOTGLYPH</code>. Both Luna as well as Aero do not define this part for the class <code>TREEVIEW</code> at all so painting with it does nothing. But Aero defines it for the subclass <code>EXPLORER</code> of the class <code>TREEVIEW</code>.</p>

<p>So when implementing a control resembling tree-view, you should use the part only conditionally by checking it is available with <code>IsThemePartDefined()</code>, and fall back to the part <code>TVP_GLYPH</code> if it is not.</p>

<p>Unfortunately, MSDN does not provide any information on which parts or states of each class are considered to be guaranteed to be defined and which are optional. Obviously, some must be guaranteed to be defined, or the painting with themes does not make much sense: Otherwise using the API would grow to the task of unrealistic complexity both for implementation as well as testing it.</p>

<p>A partial solution to this problem is using some common sense and using some utility for exploring the theme definitions: Often you may recognize what they are for from their visual appearance. There are several such utilities available on the net. I offer one, called Theme Explorer, by the end of this article.</p>

<h3>Gotcha: Not Really Designed for Custom Controls</h3>

<p>When implementing a custom control, the developer should design it to be consistent with standard controls. Arguably, one might assume that it is a purpose of such API to paint other controls consistently with the standard ones, despite the theme currently in use; and that the task should be fairly straightforward.</p>

<p>Actually the reality differs. Both the API and the way how the Windows themes are defined, often lead to frustration when trying to achieve the desired goal.</p>

<p>As an example, I remember my attempt to implement an edit control with one or more buttons similar to what a standard combo-box is equipped with. The only difference should be a different glyph on the button(s) but unlike that, its appearance should be as close to the standard control as possible.</p>

<p>Similar example would be to only reuse the combo box glyph (the drop down arrow), when one wants to present a small button for opening a drop-down menu somewhere in the application or in another custom control.</p>

<p>Unfortunately, the class <code>COMBOBOX</code> has a part <code>CP_DROPDOWNBUTTON</code> which paints not just the background of the button, but also the glyph. You can have both, or nothing.</p>

<p>Yes, the API has a dedicated function to get a bitmap from the theme (<code>GetThemeBitmap()</code>). So one might think retrieving the glyph bitmap can be done with this function. Otherwise what would the function be good for? But, seemingly, the theme definition authors have a different opinion. There is no glyph for the combo box, there are only some pixels in the background part which, to the untrained eyes of a poor user, may make a false impression that some symbol is present...</p>

<p>My personal opinion is that the theming API and especially the themes, defined the way they are, were designed by someone who was not having third party custom controls in mind at all. That's quite a pitiful situation if you ask me, as it significantly lowers the potential of the API.</p>

<h3>Gotcha: Not Used Consistently in Standard Controls</h3>

<p>However, there are also problems with standard controls.</p>

<p>When Microsoft created <em>COMCTL32.DLL</em>, they simply omitted support for some controls or their styles. A well known example is that buttons with the style <code>BS_BITMAP</code> or <code>BS_ICON</code> were painted unthemed on Windows XP although the implementation of theme paint for it is trivial once you support <code>BS_PUSHBUTTON</code>. (This was fixed in Windows Vista.)</p>

<p>In a similar way, since version 6 of the library, Microsoft made tab styles and <code>TCS_BOTTOM</code> and <code>TCS_VERTICAL</code> unsupported, and indeed, there are no data in the theme definitions corresponding to those control styles. Any custom control wanting to achieve something similar cannot rely on it at all.</p>

<p>This fairly limits how custom controls may differ (i.e., be customized) from standard ones.</p>

<p>On the contrary, there are also data in Windows theme definitions clearly intended for some purpose like determining a size, margin, or other property, but which way too often are not used by implementation of the standard controls. Instead the controls use undocumented magical constants, hard-coded in <em>COMCTL32.DLL</em>.</p>

<p>For example, when I was implementing a tree-list view control (<a href="http://mctrl.org/">mCtrl project</a>), I had encountered this issue. The control was designed to be visually as close to the standard tree-view as possible. I was expecting that, when themed, the standard control uses <code>GetThemeBackgroundContentRect()</code> to apply some margins of tree-view items when painting them. To my surprise, any attempt to use this function returned 0 for all the margins, while it is apparent the standard tree view has some margins around them (they are easy to spot if you select an item in a tree-view, there are a few pixels as margins at all the edges).</p>

<p>Said in other words: In order to create a custom control consistently with a standard one, the developer has to magically mix standard GDI with theming API and magical constants. The particular mixture is considered an implementation detail of each standard control by Microsoft, it is not documented anywhere and hence it has to be guessed or reverse-engineered. Furthermore the poor custom-control developer is then in some danger, the mixture recipe shall change in future versions of Windows. Indeed, it is not a situation which can make any developer happy.</p>

<p>The only partial solution I can offer is that developers of Wine already made a huge effort to make their controls to be as close to the originals as possible, so the easiest way is looking at their code. It is not the first time I recommend their code base, and I am pretty sure it is not the last one either. (Some links are provided by the end of this article.)</p>

<h3>Gotcha: OpenThemeData() and Windows XP</h3>

<p>According to MSDN, in <code>OpenThemeData()</code> the second parameter is more capable than just being a single class name. In particular it says the following:</p>

<ul>
	<li>It can directly open the theme subclass with <code>OpenThemeData(hwnd, L"subclass::class")</code>.</li>	<li>It can accept a list of semicolon-delimited class names, using the first one found in the theme definition.</li></ul>

<p>Both features are nice. What is not nice is the (undocumented) fact, that according to my experience they do not work on Windows XP. So for compatibility with WinXP, you need open subclasses only via <code>SetWindowTheme()</code> as explained earlier in this article.</p>

<p>The other feature can be replaced with using multiple calls of the function:</p>

<pre lang="C"><span class="code-keyword">const</span> WCHAR* pszClassList[] = { L<span class="code-string">"</span><span class="code-string">class1"</span>, L<span class="code-string">"</span><span class="code-string">class2"</span>, ..., NULL };
HTHEME hTheme = NULL;
<span class="code-keyword">int</span> i;

<span class="code-keyword">for</span>(i = <span class="code-digit">0</span>; pszClassList[i] != NULL; i++) {
    hTheme = OpenThemeData(hwnd, pszClassList[i]);
    <span class="code-keyword">if</span>(hTheme != NULL)
        <span class="code-keyword">break</span>;
}</pre>

<h3>Gotcha: GetWindowTheme() Limited to One Theme Handle</h3>

<p>When implementing a really complex control, for example a control looking as a combination of multiple standard controls, you might want to open multiple different theme handles. It is, of course, possible, but it leads to one side effect.</p>

<p>When the application calls a function <code>GetWindowTheme()</code> (and passes its <code>HWND</code> as 1st parameter) to retrieve the theme data the control uses, it can get only one of them (actually the last one opened for the given control).</p>

<p>There are two ways how to deal with it:</p>

<ol>
	<li>The control implementation should promote one of the handles to have a primary status. Only for that one theme handle the control's <code>HWND</code> should be passed into <code>OpenThemeData()</code> as its 1st parameter. For the other theme handles, <code>NULL</code> should be passed in instead.</li>	<li>Or the implementator should always guarentee the theme handles are opened in the same order in all cases, and the primary theme handle should be opened as the last one.</li></ol>

<h3>Gotcha: GetThemeIntList() Designed to Crash</h3>

<p>The function <code>GetThemeIntList()</code> and the corresponding structure <code>INTLIST</code> are mis-designed. The structure contains a member <code>iValues</code>, actually an integer array of a fixed size. Unfortunately the size depends on the preprocessor value <code>_WIN32_WINNT</code> and there is no run-time check in a similar way as many WinAPI functions do with a member typically named <code>cbSize</code>.</p>

<p>If <code>_WIN32_WINNT</code> is not defined, or is lower than 0x0600 (<code>_WIN32_WINNT_VISTA</code>), the array size is 10, otherwise it is 402. The <em>UXTHEME.DLL</em> implementation on Vista and later blindly assumes, it can write up to 402 integers into the array. I.e., if your application was built with <code>_WIN32_WINNT</code> set as for example <code>_WIN32_WINNT_WINXP</code>, you can get a buffer overrun on Vista and newer, leading likely either to application crash or other data overwrite.</p>

<p>The solution is easy: If you need to use this function, build your project with the predefined <code>_WIN32_WINNT</code> accordingly to 0x600 or higher, or use a buffer large enough to hold the complete structure with 402 integers. Hopefully Microsoft will not augment the limit further in future Windows versions.</p>

<h2>Theme Explorer</h2>

<p>I already noted that many aspects of the theming API are poorly documented. For this reason, I have developed a small tool for exploring the current theme, Theme Explorer. Originally I created it for my own purposes, when developing my custom controls, but I feel it may be useful to broader audience.</p>

<p align="center"><img alt="Theme Explorer screenshot" height="471" src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/theme-explorer.png" width="588"></p>

<div align="center" class="Caption">Screenshot of Theme Explorer</div>

<p>The left part is a selector of an object to explore (class or subclass on the first level, parts and states deeper in the tree), the right side then paints the part/state with <code>DrawThemeBackground()</code> in several sizes and lists the properties associated with the object.</p>

<p>It can be downloaded from the mCtrl project website and its sources are hosted on github:</p>

<ul>
	<li>Homepage: <a href="http://mctrl.org/tools.php">http://mctrl.org/tools.php</a></li>	<li>Code repo: <a href="https://github.com/mity/theme-explorer">https://github.com/mity/theme-explorer</a></li></ul>

<p>(The tool is licensed under GNU GPL version 2 or, at your option, any later version.)</p>

<p>The tool has some limitations: It can only explore the theme currently in use, so to be useful you have to run it on Windows XP or later (with the theming support enabled in the system). And to explore the themes in different Windows versions, you need to use this tool on each of them. Still, I hope you can find it useful.</p>

<h2>Downloadable Example</h2>

<p>You can download an example package at the top of this page. It contains a Visual Studio 2010 solution with three little projects: DLL with theme-aware custom control implementation using what this article presents, and two small applications which just host the custom control. Actually the two applications share their sources and the only difference in them is that one has an application manifest while the other one does not.</p>

<p>The DLL uses the function <code>ShouldUseUxThemeDll()</code> to detect whether it should use the themed painting or not. When the function returns <code>FALSE</code>, the DLL then uses its own <code>dummy_OpenThemeData()</code> (instead of <code>OpenThemeData()</code>) which simply returns <code>NULL</code>.</p>

<p>Only when <code>ShouldUseUxThemeDll()</code> returns <code>TRUE</code>, the example loads <em>UXTHEME.DLL</em> and the rest depends on the return value of <code>OpenThemeData()</code>.</p>

<h2>Real World Code</h2>

<p>In case you want to study real world code, I can refer to you the following:</p>

<p><a href="http://www.winehq.org/">Wine</a> reimplementation of <em>COMCTL32.DLL</em> is (mostly) aware of themes. In particular, the controls implemented historically in <em>USER32.DLL</em> are subclassed in it so in their case the source focuses only on making the controls themed which makes them perfect candidates for further studying the topic:</p>

<ul>
	<li>Themed button: <a href="https://github.com/mirrors/wine/blob/master/dlls/comctl32/theme_button.c">https://github.com/mirrors/wine/blob/master/dlls/comctl32/theme_button.c</a></li>	<li>Themed combo: <a href="https://github.com/mirrors/wine/blob/master/dlls/comctl32/theme_combo.c">https://github.com/mirrors/wine/blob/master/dlls/comctl32/theme_combo.c</a></li>	<li>Themed edit: <a href="https://github.com/mirrors/wine/blob/master/dlls/comctl32/theme_edit.c">https://github.com/mirrors/wine/blob/master/dlls/comctl32/theme_edit.c</a></li>	<li>Themed listbox: <a href="https://github.com/mirrors/wine/blob/master/dlls/comctl32/theme_listbox.c">https://github.com/mirrors/wine/blob/master/dlls/comctl32/theme_listbox.c</a></li></ul>

<p>Also its reimplementation of <em>UXTHEME.DLL</em> may be of interest for readers of this article:</p>

<ul>
	<li><em>UXTHEME.DLL</em> reimplementation: <a href="https://github.com/mirrors/wine/tree/master/dlls/uxtheme">https://github.com/mirrors/wine/tree/master/dlls/uxtheme</a></li></ul>

<p><a href="http://mctrl.org/">mCtrl</a> implements a wrapper of <em>UXTHEME.DLL</em>, to deal with the library (or some of its exported symbols) missing in dependence on particular Windows version:</p>

<ul>
	<li>Public interface: <a href="https://github.com/mity/mctrl/blob/master/include/mCtrl/theme.h">https://github.com/mity/mctrl/blob/master/include/mCtrl/theme.h</a></li>	<li>Implementation: <a href="https://github.com/mity/mctrl/blob/master/src/theme.c">https://github.com/mity/mctrl/blob/master/src/theme.c</a></li></ul>

<p>In addition to that, majority of its controls are theme-aware, using the wrapper, so lets list just few more interesting ones:</p>

<ul>
	<li>Button: <a href="https://github.com/mity/mctrl/blob/master/src/button.c">https://github.com/mity/mctrl/blob/master/src/button.c</a>, bringing themed <code>BS_ICON</code> and <code>BS_BITMAP</code> for Windows XP</li>	<li>Tree-list view: <a href="https://github.com/mity/mctrl/blob/master/src/treelist.c">https://github.com/mity/mctrl/blob/master/src/treelist.c</a></li></ul>

<h2>Next Time: Handling Standard Messages</h2>

<p>That's it for today. The article is much longer than I originally anticipated. On the other side, its length reflects the importance I attach to this topic for creation of good custom controls, and also it reflects the lack of documentation about it. I hope this text has enhanced the situation a bit and that you found at least some information presented here useful and in understandable form. Some time later we will return to control painting, for example, to discuss some animating techniques or painting into a non-client area. Even in those areas, <em>UXTHEME.DLL</em> has something to offer.</p>

<p>That said, however, we should first step aside a bit and explore other aspects of custom controls implementation. Every control should support a number of standard messages which the application and system uses to communicate with it. MSDN often documents messages from the point of an application, but we should look on them mainly from a control's point of view and that will be the subject of the next article.</p>


						</div>
						

						<div class="float-right" style="margin:20px 0 0 10px;border:1px solid #ccc">
						
						</div>
                        
                        
						
						<h2>License</h2>
						<div id="LicenseTerms"><p>This article, along with any associated source code and files, is licensed under <a href="http://www.codeproject.com/info/cpol10.aspx" rel="license">The Code Project Open License (CPOL)</a></p></div><h2 id="ctl00_AboutHeading">About the Author</h2>
						    

<div class="author-wrapper">

    <div class="pic-wrapper"> 
        <img id="ctl00_AboutAuthorRptr_ctl00_AboutAuthor_memberPhoto" class="profile-pic" src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/58de2d085c17e28b8951315245dd408c.jpeg" style="border-width:0px;transform:rotate(1deg);">
    </div>

    <div class="container-member">  
        <b><a id="ctl00_AboutAuthorRptr_ctl00_AboutAuthor_memberProfileLink" class="author" href="https://www.codeproject.com/Members/Martin-Mitas">Martin Mitáš</a></b>

        <table>
        <tbody><tr>
            <td rowspan="2" nowrap="" valign="middle">
            <div id="ctl00_AboutAuthorRptr_ctl00_AboutAuthor_FollowOn" class="follow">
	            
	            
	            <a href="https://www.linkedin.com/profile/view?id=88607525"><img style="vertical-align:middle;border:0;height:24px;width:24px" alt="LinkedIn" src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/linkedin-32.png"></a> 
            </div>
            </td>
            <td nowrap="nowrap">
                <div class="company">
                    <span id="ctl00_AboutAuthorRptr_ctl00_AboutAuthor_memberJobTitle">Team Leader</span>
	                <span id="ctl00_AboutAuthorRptr_ctl00_AboutAuthor_memberCompany"></span>
                </div>
            </td>
            <td rowspan="2" style="padding-left:15px">
                <a id="ctl00_AboutAuthorRptr_ctl00_AboutAuthor_FollowMember_FollowBtn" title="Have events related to this Member appear in your timeline" class="button unfollowed align-center invisible" data-enabletooltip="true" data-tooltip="Have the articles and posts from this member appear in your Timeline so you can stay up to date." style="display:none;">Follow<div class="tiny-text" style="margin-top:-3px;">this Member</div></a>
	<a id="ctl00_AboutAuthorRptr_ctl00_AboutAuthor_FollowMember_UnfollowBtn" title="Unfollow this Member" class="button followed align-center invisible" data-enabletooltip="true" data-tooltip="Stop following this Member" style="display:none;">Unfollow</a>

            </td>
        </tr>
        <tr>
            <td>
                <span id="ctl00_AboutAuthorRptr_ctl00_AboutAuthor_memberLocation">Czech Republic <img src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/CZ.gif" alt="Czech Republic" width="16px" height="11px"></span>
            </td>
        </tr>
        </tbody></table>
    </div>

    <div class="description">
        No Biography provided

        
    </div>

</div><br>
						
						

						<div class="clearfix"></div>

						<div style="padding-top:8px">
							
						</div>

					

				    
					</form>

				</div>

				
				<div class="bottom-promo"> 
				    
				</div>
				

                

				
				

					<h2>Comments and Discussions</h2>
					
					<p><img alt="Comment" src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/NewComment.gif" width="12px" height="16px">
					<b>12 messages</b> have been posted for this article 
					Visit <b><a id="ctl00_ArticleLink" href="https://www.codeproject.com/Articles/620045/Custom-Controls-in-Win-API-Visual-Styles">https://www.codeproject.com/Articles/620045/Custom-Controls-in-Win-API-Visual-Styles</a></b> to post and view comments on 
					this article, or click <b><a id="ctl00_PrintWithMessage" href="https://www.codeproject.com/Articles/620045/Custom-Controls-in-Win-API-Visual-Styles?display=PrintAll">here</a></b> 
					to get a print view with messages.</p>
					
				

			</div>
			
		</td>
		<td width="170px" class="article-wing-right">
			
		</td>
		</tr></tbody></table>

		
		<div class="theme1-background" style="height:2px" id="stickyStop"></div>

		<div class="extended tiny-text">
			<div class="row">
				<div class="float-left">
					<a id="ctl00_PermaLink" href="https://www.codeproject.com/Articles/620045/Custom-Controls-in-Win-API-Visual-Styles">Permalink</a> | 
					<a id="ctl00_AdvertiseLink" href="http://developermedia.com/">Advertise </a> |
					<a id="ctl00_PrivacyLink" href="https://www.codeproject.com/info/privacy.aspx">Privacy</a> |
    				<a id="ctl00_CookiePolicyLink" href="https://www.codeproject.com/info/cookies.aspx">Cookies</a> |
                    <a id="ctl00_TermsOfUseLink" href="https://www.codeproject.com/info/TermsOfUse.aspx">Terms of Use</a> |
					<a id="ctl00_Mobile">Mobile</a>
					<br>
								
					
					Web06 |
					2.8.181119.1 |
					Last Updated 17 Mar 2014								
				</div>

                      

				<div class="float-right align-right">
					Article Copyright 2013 by Martin Mitáš<br>Everything else
					Copyright © <a href="mailto:webmaster@codeproject.com">CodeProject</a>, 1999-2018 <br>
				</div>

				

			</div>
		</div>
		

		<br clear="all">
		
			

	</div> 
	</div>
</div>






<script type="text/javascript" src="./Custom Controls in Win32 API_ Visual Styles - CodeProject_files/MemberProfilePopup.min.js.下载"></script>
<script type="text/javascript">//<![CDATA[
$(document).ready(function () {
   processCodeBlocks.Initialise('#contentdiv');
   thumbnailer.Initialise('#contentdiv',700,600);
});
cookieconsent.initialise({
                                enabled : true,
                                cookie  : { domain: 'codeproject.com' },
                                palette : {
                                    popup: { background: '#ff9900' },
                                    button: { background: '#f5d948' }
                                },
                                law :  {
                                    showForAllRegions : true, 
                                    countryCode : 'CN' 
                                },
                                theme: 'edgeless',
                                type : 'opt-in',
                                content: {
                                    message: 'Like every other website we use cookies. By using our site you acknowledge that you have read and understand our <a href=\'/info/cookie.aspx\'>Cookie Policy</a>, <a href=\'/info/privacy.aspx\'>Privacy Policy</a>, and our <a href=\'/info/TermsOfUse.aspx\'>Terms of Service</a>.',
                                    href:    'https://www.codeproject.com/info/privacy.aspx'
                                },
                                revokable:true,
                                onStatusChange: function(status) {
                                    $.ajax({
                                		dataType  : 'json',
                                        data: JSON.stringify({ allowCookies : this.hasConsented() }),
                                        url: '/script/Common/webservices/CommonServices.aspx/SetCookieConsent',
                                        cache: false,
                                        type: 'POST',
                                        contentType: 'application/json'
                                    })
                                    console.log(this.hasConsented() ? 'enable cookies' : 'disable cookies');
                                    console.log(this.hasAnswered() ? 'has answered' : 'did not answer');
                                },
                            });
$(document).ready(function() { anchorAnimate();
});
$(document).ready(function(){
    $('#__EVENTVALIDATION').attr('autocomplete', 'off');
});
$(function() {
                        var followServicectl00_AboutAuthorRptr_ctl00_AboutAuthor_FollowMember = new FollowService('/script/follow/webservices/followServices.aspx/', true);
                        followServicectl00_AboutAuthorRptr_ctl00_AboutAuthor_FollowMember.initFollowObjectButtons({
                            item : { 
                                objectTypeId   : 1,
                                objectId       : 5807385
                            },
                            followButtonId   : 'ctl00_AboutAuthorRptr_ctl00_AboutAuthor_FollowMember_FollowBtn',
                            unfollowButtonId : 'ctl00_AboutAuthorRptr_ctl00_AboutAuthor_FollowMember_UnfollowBtn'
                        }, false);
                    });

//]]>
</script>





<div id="MemberProfilePopupDiv" class="raised box" style="display: none; position: absolute;"></div><div id="MemberProfilePopupDiv" class="raised box" style="display: none; position: absolute;"></div><div id="MemberProfilePopupDiv" class="raised box" style="display: none; position: absolute;"></div></body></html>